package org.example.judge_comment.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import org.example.judge_comment.common.RequestCommentParams;
import org.example.judge_comment.mapper.CommentMapper;
import org.example.judge_comment.service.CommentLikeService;
import org.example.judge_comment.service.CommentService;
import org.example.judge_common.entity.PageResult;
import org.example.judge_common.entity.RequestParams;
import org.example.judge_common.util.IdWorker;
import org.example.judge_common.util.MyUtils;
import org.example.judge_pojo.Comment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

@Service("CommentServiceImpl")
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private RedisTemplate redisTemplate;

    @Qualifier("CommentLikeServiceImpl")
    @Autowired
    private CommentLikeService commentLikeService;
    @Override
    public PageResult<Comment> search(RequestCommentParams params) {
        if(MyUtils.isEmpty(params.getField())){ //默认排序字段
            params.setField("click");
        }
        if(MyUtils.isEmpty(params.getOrder())){   //默认排序方式
            params.setOrder(RequestParams.DESC);
        }

        QueryWrapper<Comment> queryWap = new QueryWrapper<>();

        //字段模糊匹配
        if(MyUtils.isNotEmpty(params.getKey())){
            queryWap.and(new Consumer<QueryWrapper<Comment>>() { //隔离or条件
                @Override
                public void accept(QueryWrapper<Comment> problemQueryWrapper) {
                    problemQueryWrapper.like("title",params.getKey()).or().
                            like("text",params.getKey());
                }
            });

        }

        // 父级评论
        if(MyUtils.isNotEmpty(params.getFatherId())){
            queryWap.eq("father_id",params.getFatherId());
        }
        //发表人
        if(MyUtils.isNotEmpty(params.getUserId())){
            queryWap.eq("user_id",params.getUserId());
        }

        //可用
        if(params.getStatus()!=null&&params.getStatus()>=0&&params.getStatus()<=1){
            queryWap.eq("status", params.getStatus());
        }
        // 排序
        //先按权重排序
        queryWap.orderBy(true,false,"weight");
         queryWap.orderBy(true,"asc".equalsIgnoreCase(params.getOrder()),params.getField());


         //0类型，帖子Or评论
        queryWap.eq(params.getType()!=null,"type",params.getType());
        //存储的是回复的对象
        queryWap.eq(MyUtils.isNotEmpty(params.getTitle()),"title",params.getTitle());
        // 设置分页
        PageHelper.startPage(params.getPage(), params.getSize(),false);
        List<Comment> problems = this.baseMapper.selectList(queryWap);
        for (Comment problem : problems) {  //获取点赞数量
            String o = (String) redisTemplate.opsForValue().get(problem.getId());
            if(o!=null){
                Integer click = JSON.parseObject(o, Comment.class).getClick();
                problem.setClick(click);
            }

        }
        // 求数据条数
        Integer count = this.baseMapper.selectCount(queryWap);
        return new PageResult<Comment>(count.longValue(),problems);
    }

    @Override
    public boolean clickLikeSum(String id, int i) {
        boolean b = super.baseMapper.clickLikeSum(id, i);
        redisTemplate.delete(id);
        return b;
    }


    @Override
    public boolean save(Comment entity) {

        entity.setId(idWorker.nextId().toString());
        entity.setCreateTime(new Date());
        entity.setUpdateTime(new Date());
        entity.setClick(0);
        entity.setLikeSum(0);
        entity.setStatus(0);
        entity.setReplyCount(0);
        List<String> fatherIds = new ArrayList<>(4); //存储所有父回复，其实也就两层
        //获取所有父类，并其replyCount++
        Comment father = super.getById(entity.getFatherId());
        while (father!=null){
            fatherIds.add(father.getId());
            father = super.getById(father.getFatherId());  //再获取父节点
        }
        if(fatherIds.size()>0){  //更新父节点的回复数
            UpdateWrapper<Comment> updateWrapper = new UpdateWrapper<>();
            for (String fatherId : fatherIds) {
                Comment byId = super.getById(fatherId);
                if(byId!=null){
                    updateWrapper.set("reply_count",byId.getReplyCount()+1).eq("id",byId.getId());
                    super.update(updateWrapper);
                }
                updateWrapper.clear();
            }
//            updateWrapper.setSql(true,"reply_count = reply_count +1").in("id",fatherIds);
//            super.update(updateWrapper);
        }

        return super.save(entity);
    }


    @Override
    public boolean updateById(Comment entity) {
        String o = (String) redisTemplate.opsForValue().get(entity.getId());
        Comment comment = null;
        if(o!=null){  //点击量刷新到数据库
            comment = JSON.parseObject(o,Comment.class);
            entity.setClick(comment.getClick());
            if(entity.getLikeSum().intValue()==comment.getLikeSum())entity.setUpdateTime(new Date());
        }

        redisTemplate.opsForValue().set(entity.getId(),JSON.toJSONString(entity),30, TimeUnit.MINUTES);
        return super.updateById(entity);
    }


    @Override
    public Comment getById(Serializable id) {
        String o = (String) redisTemplate.opsForValue().get(id);
        Comment comment = null;
        if(o!=null){
            comment = JSON.parseObject(o,Comment.class);
            if(comment==null)return null;
        }else{
            comment = super.getById(id);
            if(comment==null)return null;
//            comment.setLikeSum(commentLikeService.countByCommentId(id));
            redisTemplate.opsForValue().set(id,JSON.toJSONString(comment),30, TimeUnit.HOURS);
        }
        comment.setClick(comment.getClick()+1);
        redisTemplate.opsForValue().set(id,JSON.toJSONString(comment),30, TimeUnit.HOURS);
        if(System.currentTimeMillis()-last>=2*60*1000) {  //每两分钟刷新一次点击量到数据库
            super.updateById(comment);
            last = System.currentTimeMillis();
        }
        return comment;
    }

    @Override
    public boolean removeById(Serializable id) {
//        redisTemplate.opsForValue().set(id,null,0, TimeUnit.MINUTES);
//获取所有父类，并其replyCount++
        Comment entity = this.getById(id);
        Comment father = super.getById(entity.getFatherId());
        List<String> fatherIds = new ArrayList<>(4); //存储所有父回复，其实也就两层
        while (father!=null){
            fatherIds.add(father.getId());
            father = super.getById(father.getFatherId());  //再获取父节点
        }
        if(fatherIds.size()>0){  //更新父节点的回复数
            UpdateWrapper<Comment> updateWrapper = new UpdateWrapper<>();
            for (String fatherId : fatherIds) {
                Comment byId = super.getById(fatherId);
                if(byId!=null){
                    updateWrapper.set("reply_count",Math.max(0,byId.getReplyCount()-1)).eq("id",byId.getId());
                    super.update(updateWrapper);
                }
                updateWrapper.clear();
            }
//            updateWrapper.setSql(true,"reply_count = reply_count +1").in("id",fatherIds);
//            super.update(updateWrapper);
        }
        boolean b = super.removeById(id);
        redisTemplate.delete(id);

        return b;
    }

    public static long last = System.currentTimeMillis();
}
